from datetime import datetime, time
from itertools import count
from typing import Coroutine
from flask import Blueprint,request,jsonify
from flask.scaffold import F
from flask.typing import ResponseReturnValue
import requests,datetime
from conf.comm import sqlalchemy_context,SECRET_KEY
from database import *
import json,re,random,time
from utils.myjwt import myjwt
import os
import uuid


from utils.rediscon import RedisCon
#容联云发送信息包
from conf.comm import send_message
from werkzeug.security import generate_password_hash,check_password_hash
#蓝图初始化
bp_users = Blueprint('users',__name__)

#注册功能实现
@bp_users.route('/reg/',methods=['POST'])
@sqlalchemy_context()
def reg():
    #获取vue信息
    data = request.data
    if not data:
        data  = request.form
    else:
        data = json.loads(request.data)

    #正则验证
    res = re.match('^1[3-9][0-9]{9}$',data['mobile'])
    if not res:
        return jsonify({'code':11111,'msg':'手机号不合法'})

    #向数据库提交数据
    try:
        user = User(username=data['username'],password=generate_password_hash(data['password']),mobile=data['mobile'])
        db.session.add(user)
        db.session.commit()
        return jsonify({'code':200,'msg':'注册成功'})
    except:
        return jsonify({'code':20020,'msg':'用户已从在'})
    
#手机短信接口
@bp_users.route('/sendcode/',methods=["POST"])
@sqlalchemy_context()
def sendcode():

    #传递手机号
    data = request.data
    if data:
        data = json.loads(data)
    else:
        data = request.form
    mobile = data['mobile']
    r = RedisCon()
    #有效性验证，正则验证手机号
    reg = re.match('^1[3-9]\d{9}$',data['mobile'])
    if not reg:
        return jsonify({"code":10012,'msg':'手机号不合法'})
    #验证是否30秒内已经发过验证码
    code  = r.get_str(mobile)
    if code:
        return jsonify({"code":10015,'msg':'30少内您已经发过验证码'})
    #生成验证码
    code = str(random.randint(100000,999999))
    #调用短信接口
    flag = send_message(mobile,code,1)
    if flag:
        #发送成功，存入redis
        r.set_str(mobile,code,60)
        #返回结果（验证码）
        return jsonify({'code':200,'sendcode':code,'msg':'发送成功，请接收'})
    else:
        return jsonify({'code':20011,'msg':'发送失败，请重试'})

#登录接口
@bp_users.route('/login/',methods=["GET"])
@sqlalchemy_context()
def login():
    #用户名登录
    username = request.args.get('username')
    password = request.args.get('password')
    mobile = request.args.get('mobile')
    code = request.args.get('code')
    # print(username,password)
    # return 'ok'
    if username:
        #查询这个用户信息 
        user = User.query.filter_by(username=username).first()
        if user:
            if check_password_hash(user.password,password):
                #密码对 删除错误的信息记录
                Record.query.filter_by(username = username).delete()
                token = myjwt.jwt_encode({'data':{'username':user.username,'userid':user.id}})
                return jsonify({'code':200,'msg':'登录成功','userid':user.id,'username':user.username,'token':token})
            else:
                #目前时间
                print('************************************************')
                day = datetime.datetime.now()
                print(day)
                #看看记录表错误有没有次数
                user = Record.query.filter_by(username = username).first()
                print(user)
                #如果没有用户就添加一个新记录
                if not user:
                    rec = Record(username=username,recordtime=day,count=1)
                    db.session.add(rec)
                    db.session.commit()
                #有数据修改 次数加一和时间更新
                else: 
                    #先判断时间 例如今天登录2次没上去不等了 然后等到24小时以后登录时间要归零 然后还有3次登录机会
                    if day.timestamp()/3600>user.recordtime.timestamp()/3600+24:
                        Record.query.filter_by(username=username).update({'count':0,'recordtime':day})
                    #没超过24小时 连续登录3次不让登录
                    if user.count <3:
                        Record.query.filter_by(username=username).update({'count':user.count+1})
                        db.session.commit()
                    elif user.count ==3:
                        return jsonify({'code':20060,'msg':'每天只有三次登录机会'})
                    
                        

                return jsonify({'code':20030,'msg':'用户名或密码错误'}) 
        else:
            return jsonify({'code':20020,'msg':'该用户不存在'})

    if mobile:    
        #手机号登录
        #获取前端验证码
        #获取后台验证码
        r=RedisCon()
        hcode = r.get_str(mobile)  #得到的是b开头的二进制数据
        print(hcode)
        if hcode:
            if int(code) == int(hcode):
                #写到数据库
                user = User.query.filter_by(mobile=mobile).first()
                if not user:
                    user = User(mobile=mobile,username=mobile)
                    db.session.add(user)
                    db.session.commit()
                r.del_str(mobile)
                token = myjwt.jwt_encode({'data':{'mobile':user.mobile,'userid':user.id}})
                return jsonify({'code':200,'msg':'登录成功','userid':user.id,'username':user.username,'token':token})
            else:
                return jsonify({'code':20050,'msg':'验证码输入错误，请重新输入'})
        else:
            return jsonify({'code':20040,'msg':'验证码不存在'})

#中间件 token除了注册和登录 其余都使用
@bp_users.before_request
def before_request():
    lst=['/users/login/','/users/sendcode/','/users/reg/']
    if request.path not in lst:
        #获取token
        try:
            token = request.headers['Token']
        except:
            return jsonify({"code":403,'mes':'请传递token'})
        #解密重新对比token
        newtoken = myjwt.jwt_decode(token)
        # print(token)
        # print(newtoken)
        if newtoken and myjwt.check(token,newtoken):
            pass
        else:
            return jsonify({"code":403,'mes':'token错误'})






#用户中心
#返回用户信息接口
@bp_users.route('/getuserinfo/',methods=['GET'])
def getuserinfo():

    userid = request.args.get('userid')
    # print(userid)
    user = User.query.filter_by(id=userid).first()
    # print(user)
    
    dic={}
    dic['id']=user.id
    dic['username']=user.username
    dic['mobile']=user.mobile
    dic['avater']=user.avater

    return jsonify({'code':200,'list':dic})


#图像上传
@bp_users.route('/upload/',methods=["POST"])
def upload():
    #接收
    file = request.files['file']
    print(file)
    
    #解决文件重命名问题
    #1uuid 设计到后缀  后缀不变用os.path.splitex【1】分割 在使用uuid凭借
    filetext= os.path.splitext(file.filename)[1]  #获取到的是.jpg .png
    newfilename = uuid.uuid4().hex + filetext                #uuid4格式456-66asd-a  加hex变asd5asd6a54d  -有时候会出问题
    #重新创建一个文件 根据userid来创建
    userid = request.form.get('userid')
    #判断有没有该用户名文件夹，存在直接写文件 不从在创建在写入
    path = './static/upload/'+str(userid)
    #判断不从在 创建文件夹
    if not os.path.exists(path):
        os.mkdir(path)

    #收到保存在upload  
    file.save(os.path.join(path,newfilename))

    #更新到数据库
    User.query.filter_by(id=userid).update({'avater':newfilename})
    db.session.commit()
    return jsonify({'code':200,'filename':newfilename})


#作业 添加展示 和钩子函数
@bp_users.route('/newshow/',methods=['POST','GET'])
def Newshow():
    if request.method == 'POST':
        file = request.files['img']
        print(file)
        name = request.form['name']
        print('name')
        filetext= os.path.splitext(file.filename)[1]  
        newfilename = uuid.uuid4().hex + filetext 
        path = './static/upload/'
    #判断不从在 创建文件夹
        if not os.path.exists(path):
            os.mkdir(path)

    #收到保存在upload  
        file.save(os.path.join(path,newfilename))
        cou = Course(name=name,img=newfilename)
        db.session.add(cou)
        db.session.commit()
        return jsonify({'code':200})

    elif request.method == 'GET':
        # name = request.args.get['name']
        # user = Course.query.filter_by(name=name).first()
        dic={}
        dic['id']=user.id
        dic['name']=user.name
        dic['img']=user.img

        return jsonify({'code':200,'list':dic})
    
    


